﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using RAP.Framework.Libary.Utils;

namespace RAP.Framework.Libary.Payment.WxPay
{
  /// <summary>
  /// 订单数据实体基类
  /// </summary>
  public abstract class PayDataBase : SortedDictionary<string, object>
  {
    /// <summary>
    /// 微信开放平台审核通过的应用APPID（请登录open.weixin.qq.com查看，注意与公众号的APPID不同）
    /// </summary>
    public virtual string AppId { get => this.ToString("appid"); set => this["appid"] = value; }

    /// <summary>
    /// 微信支付分配的商户号

    /// </summary>
    public virtual string MarketId { get => this.ToString("mch_id"); set => this["mch_id"] = value; }

    /// <summary>
    /// 终端设备号(门店号或收银设备ID)，默认请传"WEB"
    /// </summary>
    public virtual string DeviceInfo { get => this.ToString("device_info"); set => this["device_info"] = value; }

    /// <summary>
    /// 随机字符串，不长于32位。
    /// </summary>
    public virtual string Salt { get => this.ToString("nonce_str"); set => this["nonce_str"] = value; }

    /// <summary>
    /// 签名
    /// </summary>
    public virtual string Sign { get => this.ToString("sign"); set => this["sign"] = value; }

    /// <summary>
    /// 支付类型
    /// </summary>
    public virtual string TradeType { get => this.ToString("trade_type"); set => this["trade_type"] = value; }

    /// <summary>
    /// 
    /// </summary>
    public virtual PayConfig Config { get; set; }

    public PayDataBase()
    {

    }

    /// <summary>
    /// 序列化成XML
    /// </summary>
    /// <returns></returns>
    public virtual string ToXML()
    {
      var xml = new StringBuilder("<xml>");

      foreach (var pair in this)
      {
        var key = pair.Key;
        var value = pair.Value;
        if (value.IsNotNullOrEmpty())
        {
          if (value.IsNumber(false))
          {
            xml.Append($"<{key}>{value}</{key}>");
          }
          else
          {
            xml.Append($"<{key}><![CDATA[{value}]]></{key}>");
          }
        }
      }
      xml.Append("</xml>");
      return xml.ToString();
    }

    public static T ParseXML<T>(string xml) where T : PayDataBase
    {
      if (xml.IsNullOrEmpty())
      {
        throw new PayException("将空的xml串转换为WXPay::OrderData不合法");
      }
      var orderData = typeof(T).CreateInstance<T>();
      var xmlDoc = new XmlDocument();
      xmlDoc.LoadXml(xml);
      var rootNode = xmlDoc.FirstChild;
      foreach (XmlNode node in rootNode.ChildNodes)
      {
        orderData[node.Name] = node.InnerText;
      }
      return orderData;
    }

    /**
    * @Dictionary格式转化成url参数格式
    * @ return url格式串, 该串不包含sign字段值
    */
    public virtual string ToUrlParams()
    {
      var buff = new List<string>();
      foreach (var pair in this)
      {
        var key = pair.Key;
        var value = pair.Value;
        if (key != "sign" && value.IsNotNullOrEmpty())
        {
          buff.Add($"{key}={value}");
        }
      }
      return buff.Join("&");
    }
  }
}
